package personal.lijun.skeleton.web.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import personal.lijun.skeleton.web.feign.CalendarServiceFeign;
import personal.lijun.skeleton.web.feign.CalendarUser;

/**
 * @Auther: lijun@sstcsoft.com
 * @Date: 2019/9/16 15:08
 */
@Component
public class SpringSecurityUserContext implements UserContext{
    private static final Logger logger = LoggerFactory
            .getLogger(SpringSecurityUserContext.class);

    private final CalendarServiceFeign calendarService;
    private final UserDetailsService userDetailsService;

    @Autowired
    public SpringSecurityUserContext(final CalendarServiceFeign calendarService,final UserDetailsService userDetailsService){
        if (calendarService == null) {
            throw new IllegalArgumentException("calendarService cannot be null");
        }
        if (userDetailsService == null) {
            throw new IllegalArgumentException("userDetailsService cannot be null");
        }
        this.calendarService=calendarService;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public CalendarUser getCurrentUser() {
        SecurityContext securityContext = SecurityContextHolder.getContext();
        Authentication authentication = securityContext.getAuthentication();
        if(authentication == null){
            return null;
        }
        CalendarUser calendarUser = (CalendarUser)authentication.getPrincipal();
        String email = calendarUser.getEmail();
        if(calendarUser.getEmail() == null){
            return null;
        }
        calendarUser = calendarService.findUserByEmail(calendarUser.getEmail());
        if (calendarUser == null) {
            throw new IllegalStateException(
                    "Spring Security is not in synch with CalendarUsers. Could not find user with email " + email);
        }

        logger.info("CalendarUser: {}", calendarUser);
        return calendarUser;
    }


    @Override
    public void setCurrentUser(CalendarUser user) {
        if (user == null) {
            throw new IllegalArgumentException("user cannot be null");
        }
        UserDetails userDetails = userDetailsService.loadUserByUsername(user.getEmail());
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails,
                user.getPassword(), userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
}
